package com.hooper.online.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cameron.servicebase.config.exception.BusinessException;
import com.hooper.online.client.UserCenterClient;
import com.hooper.online.entity.DailyStatistics;
import com.hooper.online.mapper.StatisticsMapper;
import com.hooper.online.service.StatisticsService;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * @author Tim Hooper
 * @version 1.0
 * @time 2022/11/13/20:39
 */
@Slf4j
@Service
public class StatisticsServiceImpl extends ServiceImpl<StatisticsMapper, DailyStatistics> implements StatisticsService {


    @Resource
    private UserCenterClient userCenterClient;

    @Override
    @Transactional
    public DailyStatistics statistics(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date parseDate = sdf.parse(date);
            if (sdf.parse(LocalDate.now().toString()).before(parseDate)) {
                throw new BusinessException(5000, "不可生成" + LocalDateTime.now() + "之后的数据");
            }
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
        String now = LocalDate.now().toString();
        if (date.equals(now)) {
            log.info("当前日期:{}", now);
            //若统计今天的数据则先删除再添加,避免同一日期添加多条记录
            baseMapper.delete(
                    new LambdaQueryWrapper<DailyStatistics>().eq(DailyStatistics::getDateCalculated, date)
            );
        } else {
            //若统计的为之前的数据，则先查询之前是否有该数据，有则返回，无则统计
            LambdaQueryWrapper<DailyStatistics> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DailyStatistics::getDateCalculated, date);
            DailyStatistics res = baseMapper.selectOne(wrapper);
            if (res != null) {
                return res;
            }
        }
        //获取注册人数
        Integer registerCount = userCenterClient.countRegisterByDate(date);
        registerCount = RandomUtils.nextInt(1, 200);
        DailyStatistics dailyStatistics = new DailyStatistics();
        //设置统计的日期
        dailyStatistics.setDateCalculated(date);
        //设置注册人数
        dailyStatistics.setRegisterNum(registerCount);
        //其余用随机数代替
        dailyStatistics.setCourseNum(RandomUtils.nextInt(10, 2000));
        dailyStatistics.setVideoViewNum(RandomUtils.nextInt(20, 4000));
        dailyStatistics.setLoginNum(RandomUtils.nextInt(300, 2000));

        //将数据存入数据库
        this.save(dailyStatistics);
        return dailyStatistics;
    }

    @Override
    public Map<String, Object> queryChartData(String type, String start, String end) {
        QueryWrapper<DailyStatistics> wrapper = new QueryWrapper<>();
        wrapper.select("date_calculated", type)
                .between("date_calculated", start, end);
        List<DailyStatistics> statisticsList = baseMapper.selectList(wrapper);

        Map<String, Object> chartData = new HashMap<>(32);
        List<String> xAxios = new ArrayList<>(statisticsList.size());
        List<Integer> yAxios = new ArrayList<>(statisticsList.size());
        statisticsList.forEach(item -> {
            xAxios.add(item.getDateCalculated());
            switch (type) {
                case "register_num":
                    yAxios.add(item.getRegisterNum());
                    break;
                case "login_num":
                    yAxios.add(item.getLoginNum());
                    break;
                case "course_num":
                    yAxios.add(item.getCourseNum());
                    break;
                case "video_view_num":
                    yAxios.add(item.getVideoViewNum());
                    break;
                default:
                    throw new BusinessException(4004, "no such type exceptions");
            }
        });
        chartData.put("x", xAxios);
        chartData.put("y", yAxios);
        return chartData;
    }
}
